package com.example.controller;

import com.example.common.ApiResult;
import com.example.dto.LoginRequest;
import com.example.dto.LoginResponse;
import com.example.entity.Admin;
import com.example.service.AdminService;
import com.example.service.OnlineUserTrackerService;
import com.example.service.TokenStoreService;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Value;
import com.example.util.AuthUtils;
import com.example.util.JwtUtils;
import com.example.util.PasswordUtils;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "管理员管理", description = "管理员信息的增删改查操作")
@RestController
@RequestMapping("/api/admin")
public class AdminController {
    
    @Autowired 
    private AdminService adminService;
    
    @Autowired
    private JwtUtils jwtUtils;

    @Value("${app.auth.token-ttl-seconds:0}")
    private long tokenTtlSeconds;
    
    @Autowired
    private PasswordUtils passwordUtils;

    @Autowired
    private ObjectProvider<OnlineUserTrackerService> onlineUserTrackerProvider;

    @Autowired
    private ObjectProvider<TokenStoreService> tokenStoreProvider;

    @Operation(summary = "管理员登录", description = "管理员登录，成功后返回JWT Token")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "登录成功"),
            @ApiResponse(responseCode = "-1", description = "用户名或密码错误")
    })
    @PostMapping("/login")
    public ApiResult<LoginResponse> login(@RequestBody LoginRequest loginRequest) {
        // 根据用户名查询管理员
        Admin admin = adminService.findByUsername(loginRequest.getUsername());
        
        if (admin == null) {
            return ApiResult.error("用户名不存在");
        }
        
        // 验证密码
        boolean passwordVerified = passwordUtils.verifyPassword(loginRequest.getPassword(), admin.getSalt(), admin.getPassword());
        
        if (!passwordVerified) {
            return ApiResult.error("密码错误");
        }
        
        // 生成JWT Token（包含用户ID和用户名）
        String token = jwtUtils.generateToken(admin.getId(), admin.getUsername());
        
        // 构造用户信息
        LoginResponse.UserInfo userInfo = new LoginResponse.UserInfo(
            admin.getId(),
            admin.getUsername(),
            admin.getEmail(),
            "ADMIN"
        );
        
        // 计算过期时间：与 jwt.expiration 保持一致（小时）
        Long expireTime = System.currentTimeMillis() + jwtUtils.getExpirationHours() * 60 * 60 * 1000;

        // 若启用 Redis，则保存 token，TTL 优先使用 app.auth.token-ttl-seconds，其次与 jwt.expiration 对齐
        long defaultTtlSec = jwtUtils.getExpirationHours() * 60 * 60;
        long configuredTtlSec = tokenTtlSeconds > 0 ? tokenTtlSeconds : defaultTtlSec;
        tokenStoreProvider.ifAvailable(store -> store.saveToken(admin.getId(), token, configuredTtlSec));
        
        System.out.println("管理员 " + admin.getUsername() + " 登录成功，生成的 Token: " + token);
        // 记录在线（仅当存在 OnlineUserTracker Bean 时）
        onlineUserTrackerProvider.ifAvailable(tracker -> {
            System.out.println("==============test===============");
            long online = tracker.onLogin(admin.getId(), admin.getUsername());
            System.out.println("当前在线人数: " + online);
        });

        LoginResponse response = new LoginResponse(token, userInfo, expireTime);
        return ApiResult.success("登录成功", response);
    }

    @Operation(summary = "获取管理员列表", description = "获取管理员列表", 
               security = @SecurityRequirement(name = "bearerAuth"))
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "获取成功"),
            @ApiResponse(responseCode = "-1", description = "获取失败")
    })
    @GetMapping
    public ApiResult<List<Admin>> list() {
        List<Admin> admins = adminService.list();
        return ApiResult.success("查询管理员列表成功", admins);
    }

    @Operation(summary = "根据ID获取管理员", description = "根据管理员ID获取单个管理员详细信息", 
               security = @SecurityRequirement(name = "bearerAuth"))
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "获取成功"),
            @ApiResponse(responseCode = "-1", description = "管理员不存在")
    })
    @GetMapping("/{id}")
    public ApiResult<Admin> get(
            @Parameter(description = "管理员ID", required = true) 
            @PathVariable Long id) {
        Admin admin = adminService.getById(id);
        if (admin == null) {
            return ApiResult.notFound("管理员不存在");
        }
        return ApiResult.success("查询管理员成功", admin);
    }

    // 新增管理员（自动加密密码）
    @Operation(summary = "注册管理员", description = "创建新管理员，密码会自动加密存储")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "注册成功"),
            @ApiResponse(responseCode = "-1", description = "注册失败")
    })
    @PostMapping
    public ApiResult<Admin> register(@RequestBody Admin admin) {
        // 检查用户名是否已存在
        Admin existingAdmin = adminService.findByUsername(admin.getUsername());
        if (existingAdmin != null) {
            return ApiResult.error("用户名已存在");
        }
        
        // 加密密码
        PasswordUtils.PasswordResult passwordResult = passwordUtils.generatePasswordAndSalt(admin.getPassword());
        admin.setPassword(passwordResult.getEncryptedPassword());
        admin.setSalt(passwordResult.getSalt());
        
        boolean success = adminService.save(admin);
        if (!success) {
            return ApiResult.error("添加管理员失败");
        }
        
        // 返回时隐藏密码和盐值
        admin.setPassword("****");
        admin.setSalt("****");
        return ApiResult.success("添加管理员成功", admin);
    }
    
    @Operation(summary = "更新管理员信息", description = "根据ID更新管理员信息", 
               security = @SecurityRequirement(name = "bearerAuth"))
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "更新成功"),
            @ApiResponse(responseCode = "-1", description = "更新失败，管理员不存在")
    })
    @PutMapping("/{id}")
    public ApiResult<Admin> update(
            @Parameter(description = "管理员ID", required = true) 
            @PathVariable Long id, 
            @Parameter(description = "更新的管理员信息", required = true) 
            @RequestBody Admin admin) {
        // 不允许前端传递salt，强制置空
        admin.setSalt(null);
        admin.setId(id);

        // 查询原有管理员信息
        Admin dbAdmin = adminService.getById(id);
        if (dbAdmin == null) {
            return ApiResult.notFound("更新失败，管理员不存在");
        }

        // 只要前端传递了新密码，就自动加密并生成新salt，否则保持原密码和salt
        if (admin.getPassword() != null && !admin.getPassword().isEmpty()) {
            PasswordUtils.PasswordResult passwordResult = passwordUtils.generatePasswordAndSalt(admin.getPassword());
            admin.setPassword(passwordResult.getEncryptedPassword());
            admin.setSalt(passwordResult.getSalt());
        } else {
            // 没有传递新密码，保持原密码和salt
            admin.setPassword(dbAdmin.getPassword());
            admin.setSalt(dbAdmin.getSalt());
        }

        boolean success = adminService.updateById(admin);
        if (!success) {
            return ApiResult.notFound("更新失败，管理员不存在");
        }
        // 返回时隐藏密码和盐值
        admin.setPassword("****");
        admin.setSalt("****");
        return ApiResult.success("更新管理员成功", admin);
    }

    @Operation(summary = "删除管理员", description = "根据ID删除管理员信息（不能删除自己）", 
               security = @SecurityRequirement(name = "bearerAuth"))
    @ApiResponses(value = {
            @ApiResponse(responseCode = "0", description = "删除成功"),
            @ApiResponse(responseCode = "-1", description = "删除失败，管理员不存在或不能删除自己")
    })
    @DeleteMapping("/{id}")
    public ApiResult<String> delete(
            @Parameter(description = "管理员ID", required = true) 
            @PathVariable Long id) {
        
        // 获取当前登录的管理员ID（直接从JWT Token中获取）
        Long currentUserId = AuthUtils.getCurrentUserId();
        if (currentUserId == null) {
            return ApiResult.unauthorized("未找到当前用户信息");
        }
        
        // 检查是否试图删除自己
        if (currentUserId.equals(id)) {
            return ApiResult.error("不能删除自己的账号");
        }
        
        // 检查要删除的管理员是否存在
        Admin targetAdmin = adminService.getById(id);
        if (targetAdmin == null) {
            return ApiResult.error("删除失败，管理员不存在");
        }
        
        // 执行删除操作
        boolean success = adminService.removeById(id);
        if (!success) {
            return ApiResult.error("删除管理员失败");
        }
        
        return ApiResult.success("删除管理员成功", "已删除管理员: " + targetAdmin.getUsername());
    }

}
